package com.ecarx.vhaltests.hy11.testcases.climate;

import android.car.VehicleAreaSeat;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;

import com.ecarx.vhaltests.CallbackTimer;
import com.ecarx.vhaltests.IpcpClient;
import com.ecarx.vhaltests.VehicleConstants;
import com.ecarx.vhaltests.VhalUnitTestBase;
import com.ecarx.xui.adaptapi.car.IWrapper;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

import androidx.test.platform.app.InstrumentationRegistry;

import static com.ecarx.xui.adaptapi.car.hvac.IHvac.HVAC_FUNC_ECO_SWITCH;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class HvacEcoSwitchTest extends VhalUnitTestBase {
    private static int propertyId;
    private CallbackTimer cbkTimer = new CallbackTimer();
    private CarPropertyManager.CarPropertyEventCallback propertyCbk;
    private static IpcpClient ipcpClient;
    private boolean isFirstCbk;
    private static final int HVAC_ECO_SWITCH_AREA = VehicleAreaSeat.SEAT_ROW_1_LEFT | VehicleAreaSeat.SEAT_ROW_1_RIGHT |
            VehicleAreaSeat.SEAT_ROW_2_LEFT | VehicleAreaSeat.SEAT_ROW_2_RIGHT |
            VehicleAreaSeat.SEAT_ROW_2_CENTER;

    @BeforeClass
    public static void testInit() {
        IWrapper wrapper = com.ecarx.xui.adaptapi.car.Car.createWrapper(InstrumentationRegistry.getInstrumentation().getTargetContext());
        IWrapper.IPropertyId wrapperPropertyId = wrapper.getWrappedPropertyId(IWrapper.WrappedIdType.ID_TYPE_FUNCTION, HVAC_FUNC_ECO_SWITCH);
        propertyId = wrapperPropertyId.getPropertyId();
        setAvailable(true);
        Assert.assertTrue(isAvail());
    }

    @Test
    public void test001_SetHvacEcoSwitchOpen() {
        setValue(true);
        Assert.assertTrue(getValue());
    }

    @Test
    public void test002_SetHvacEcoSwitchClose() {
        setValue(false);
        Assert.assertFalse(getValue());
    }

    @Test
    public void test003_SetHvacEcoSwitchCbk() {
        isFirstCbk = true;
        setValue(false);
        propertyCbk = new CarPropertyManager.CarPropertyEventCallback() {
            @Override
            public void onChangeEvent(CarPropertyValue carPropertyValue) {
                if (isFirstCbk) {
                    isFirstCbk = false;
                } else {
                    boolean value = (boolean) carPropertyValue.getValue();
                    Assert.assertTrue(value);
                    mCarPropertyMgr.unregisterCallback(propertyCbk);
                    cbkTimer.finish();
                }
            }

            @Override
            public void onErrorEvent(int i, int i1) {
            }
        };
        mCarPropertyMgr.registerCallback(propertyCbk, propertyId, CarPropertyManager.SENSOR_RATE_ONCHANGE);
        setValue(true);
        cbkTimer.start();
    }

    @Test
    public void test004_SetHvacEcoSwitchUnAvail() {
        setAvailable(false);
        Assert.assertFalse(isAvail());
    }

    private static void setAvailable(boolean isAvail) {
        boolean isFirstSet = false;
        if (ipcpClient == null) {
            ipcpClient = new IpcpClient();
            isFirstSet = true;
        }
        int cemSvcId = 37;
        int cemOperId = 999;
        int[] cemOperIds = {999};

        int climateSvcId = 112;
        int[] climateOperIds = {200};

        int ccSvcId = 135;
        int ccOperId = 200;
        int[] ccOperIds = {200};
        int[] configs = {13};
        int[] values = {4};
        if (isFirstSet) {
            ipcpClient.setConfig(cemSvcId, cemOperIds);
            ipcpClient.setConfig(ccSvcId, ccOperIds);
            ipcpClient.setConfig(climateSvcId, climateOperIds);
        }
        String[] climates = {"paclfanlevel.data"};
        int[] climateValues = {1};
        boolean climateRet = ipcpClient.setClimaSignal(climateSvcId, climateOperIds[0], climates, climateValues);
        Assert.assertTrue(climateRet);
        String[] cems = {"vehModMngtGlbSafe1CarModSts1", "vehModMngtGlbSafe1UsgModSts"};
        int[] cemValues = {isAvail ? VehicleConstants.CAR_MODE_NOMAL : VehicleConstants.CAR_MODE_TRANSPORT, VehicleConstants.USG_MODE_CONVENIENCE};
        boolean cemRet = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        Assert.assertTrue(cemRet);
        boolean ccRet = ipcpClient.setCarconfigSignal(ccSvcId, ccOperId, configs, values);
        Assert.assertTrue(ccRet);
    }

    private void setValue(boolean value) {
        setAvailable(true);
        delay();
        mCarPropertyMgr.setBooleanProperty(propertyId, HVAC_ECO_SWITCH_AREA, value);
    }

    private boolean getValue() {
        delay();
        return mCarPropertyMgr.getBooleanProperty(propertyId, HVAC_ECO_SWITCH_AREA);
    }

    private static boolean isAvail() {
        delay();
        return mCarPropertyMgr.isPropertyAvailable(propertyId, HVAC_ECO_SWITCH_AREA);
    }
}